﻿#ifndef REMOTEOBJECT_H
#define REMOTEOBJECT_H

#include <memory>
#include "workcondition.h"
#include "ReflectableObject.h"
#include "variant.h"
#include "ReflectX_global.h"


//定义远程属性
#define RO_DECL_PROPERTY(type, name) \
public:\
void Set##name(type value){\
    static int idx = GetMetaInfo().IndexOfProperty(#name);\
    __RMTSetValue(idx,Variant::FromValue<type>(value));\
}\
type Get##name() const{\
    static int idx = GetMetaInfo().IndexOfProperty(#name);\
    return __RMTGetValue(idx).Value<type>();\
}\
Signal<type> name##Changed;\
private:\
void Set##name##Imp(type value);\
type Get##name##Imp() const;\


//简化定义属性,无需再定义访问器实现
#define RO_DECL_PROPERTY_SIMPLE(type,name) \
public:\
void Set##name(type value){\
    static int idx = GetMetaInfo().IndexOfProperty(#name);\
    __RMTSetValue(idx,Variant::FromValue<type>(value));\
}\
type Get##name() const{\
    static int idx = GetMetaInfo().IndexOfProperty(#name);\
    return __RMTGetValue(idx).Value<type>();\
}\
Signal<type> name##Changed;\
private:\
type m_##name;\
void Set##name##Imp(type value){\
	if(m_##name == value)return;\
	m_##name = value;\
	name##Changed(m_##name);\
}\
type Get##name##Imp() const{\
	return m_##name;\
}\


#define RO_BEGIN_META_PROPERTY(name) \
META_BEGIN_FUNCTION(Set##name##Imp)\
META_MEMBER_INFO(RO_PROPERTY_SETTER)\
META_END_FUNCTION;\
META_BEGIN_FUNCTION(Get##name##Imp)\
META_MEMBER_INFO(RO_PROPERTY_GETTER)\
META_END_FUNCTION;\
\
META_BEGIN_SIGNAL(name##Changed)\
META_MEMBER_INFO(RO_NOTIFIER)\
META_END_SIGNAL;\
\
META_BEGIN_PROPERTY(name)\
META_ADD_GETTER(Get##name)\
META_ADD_SETTER(Set##name)\
META_ADD_NOTIFIER(name##Changed)\
META_MEMBER_INFO(RO_PROPERTY)\




#define RO_END_META_PROPERTY \
META_END_PROPERTY;

#define __RO_FuncIndex(name,...) \
    GetMetaInfo().IndexOfFunction(#name\
    "("\
    #__VA_ARGS__\
    ")");\


//定义无参无返回值远程函数
#define RO_DECL_FUNCTION_0(name)\
public:\
void name(){\
    static int idx = __RO_FuncIndex(name);\
    Invoke(idx,false);\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(){\
    static int idx = __RO_FuncIndex(name);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true);\
    return future;\
}\
private:\
void name##Imp();\

//定义无参有返回值远程函数
#define RO_DECL_FUNCTION_0_R(name,R)\
public:\
R name(){\
    static int idx = __RO_FuncIndex(name);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true);\
    future->WaitForFinished(true);\
    return future->GetReturnValue().Value<R>();\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(){\
    static int idx = __RO_FuncIndex(name);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true);\
    return future;\
}\
private:\
R name##Imp();\


//定义1参无返回值远程函数
#define RO_DECL_FUNCTION_1(name,T1,p1)\
public:\
void name(T1 p1){\
    static int idx = __RO_FuncIndex(name,T1);\
    Invoke(idx,false,p1);\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1){\
    static int idx = __RO_FuncIndex(name,T1);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1);\
    return future;\
}\
private:\
void name##Imp(T1 p1);\

//定义1参有返回值远程函数
#define RO_DECL_FUNCTION_1_R(name,R,T1,p1)\
public:\
R name(T1 p1){\
    static int idx = __RO_FuncIndex(name,T1);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1);\
    future->WaitForFinished(true);\
    return future->GetReturnValue().Value<R>();\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1){\
    static int idx = __RO_FuncIndex(name,T1);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1);\
    return future;\
}\
private:\
R name##Imp(T1 p1);\


//定义2参无返回值远程函数
#define RO_DECL_FUNCTION_2(name,T1,p1,T2,p2)\
public:\
void name(T1 p1,T2 p2){\
    static int idx = __RO_FuncIndex(name,T1,T2);\
    Invoke(idx,false,p1,p2);\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1,T2 p2){\
    static int idx = __RO_FuncIndex(name,T1,T2);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2);\
    return future;\
}\
private:\
void name##Imp(T1 p1,T2 p2);\

//定义2参有返回值远程函数
#define RO_DECL_FUNCTION_2_R(name,R,T1,p1,T2,p2)\
public:\
R name(T1 p1,T2 p2){\
    static int idx = __RO_FuncIndex(name,T1,T2);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2);\
    future->WaitForFinished(true);\
    return future->GetReturnValue().Value<R>();\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1,T2 p2){\
    static int idx = __RO_FuncIndex(name,T1,T2);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2);\
    return future;\
}\
private:\
R name##Imp(T1 p1,T2 p2);\


//定义3参无返回值远程函数
#define RO_DECL_FUNCTION_3(name,T1,p1,T2,p2,T3,p3)\
public:\
void name(T1 p1,T2 p2,T3 p3){\
    static int idx = __RO_FuncIndex(name,T1,T2,T3);\
    Invoke(idx,false,p1,p2,p3);\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1,T2 p2,T3 p3){\
    static int idx = __RO_FuncIndex(name,T1,T2,T2);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2,p3);\
    return future;\
}\
private:\
void name##Imp(T1 p1,T2 p2,T3 p3);\

//定义3参有返回值远程函数
#define RO_DECL_FUNCTION_3_R(name,R,T1,p1,T2,p2,T3,p3)\
public:\
R name(T1 p1,T2 p2,T3 p3){\
    static int idx = __RO_FuncIndex(name,T1,T2,T3);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2,p3);\
    future->WaitForFinished(true);\
    return future->GetReturnValue().Value<R>();\
}\
std::shared_ptr<WorkFuture<Variant>> name##Async(T1 p1,T2 p2,T3 p3){\
    static int idx = __RO_FuncIndex(name,T1,T2,T3);\
    std::shared_ptr<WorkFuture<Variant>> future = Invoke(idx,true,p1,p2,p3);\
    return future;\
}\
private:\
R name##Imp(T1 p1,T2 p2,T3 p3);\

#define RO_BEGIN_META_FUNCTION_X(name,...) \
META_BEGIN_FUNCTION_X(name##Imp,__VA_ARGS__) \
META_MEMBER_INFO(RO_FUNCTION_IMP)\
META_END_FUNCTION;\
META_BEGIN_FUNCTION(name) \
META_MEMBER_INFO(RO_FUNCTION)\


#define RO_BEGIN_META_FUNCTION(name) \
META_BEGIN_FUNCTION(name##Imp) \
META_MEMBER_INFO(RO_FUNCTION_IMP)\
META_END_FUNCTION;\
META_BEGIN_FUNCTION(name) \
META_MEMBER_INFO(RO_FUNCTION)\



#define RO_END_META_FUNCTION \
META_END_FUNCTION; \

#define RO_DECL_SIGNAL(name,...) \
public:\
Signal<__VA_ARGS__> name;\


#define RO_BEGIN_META_SIGNAL(name) \
META_BEGIN_SIGNAL(name)\
META_MEMBER_INFO(RO_SIGNAL)\


#define RO_END_META_SIGNAL \
META_END_SIGNAL\

class RemoteObjectNodeBase;
class RemoteObjectNode;
class RemoteObjectHost;
struct DynamicMetaInfoData;

class REFLECTX_EXPORT RemoteObject:public ReflectableObject
{
public:
    enum Role{
        R_Independent,//该对象独立存在
        R_Source,//该对象是源
        R_Replica//该对象是副本
    };

    enum Status{
        S_None,//该对象是源，并且没有开始共享
        S_Uninited,//该对象是副本，且还未进行初始化
        S_Normal,//该对象正在共享或同步
        S_Suspecious//该对象是副本，并且与源的同步不正常
    };

public:
    REFLECTABLE(RemoteObject, ReflectableObject);
    RemoteObject();
    ~RemoteObject();

    Role GetRole() const;//获取该对象的角色
    Status GetStatus() const;//获取该对象的状态

    template<typename ...Args>
    std::shared_ptr<WorkFuture<Variant>> Invoke(int index,bool Async,Args...args){
        constexpr int paramsize = sizeof... (args);
		constexpr int paramsize_ = std::max(1,paramsize);
        const void* param[std::max(1, paramsize_)] = {(&args)...};
        return Invoke(index,param, Async);
    }

protected:
    void __RMTSetValue(int idx, Variant value);
    Variant __RMTGetValue(int idx) const;
    RemoteObjectNodeBase* GetNode();
	virtual void UpdateValue(int idx,Variant value);
	unsigned long long GetTypeSignature();
	virtual unsigned long long DoGetTypeSignature();
public:
    Signal<> Initialized;
private:
    std::shared_ptr<WorkFuture<Variant>> Invoke(int index,const void** param,bool Sync);
    void SetStatus(Status status);
    void SetRole(Role role);
private:
    struct PrivateCreate{
        RemoteObjectNodeBase* node;
        Role role;
        Status status;
    };
    void PrivateInit(PrivateCreate& p);

private:
    struct Private;
    std::unique_ptr<Private> _P;
    friend class RemoteObjectNode;
    friend class RemoteObjectHost;
};

#endif // REMOTEOBJECT_H
